package hydrap2p.speedsender;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;

import hydrap2p.ServiceLocation;
import hydrap2p.helper.ServiceConnector;
import hydrap2p.servicemanager.ServiceManager;
import hydrap2p.speedlistener.SpeedListener;

import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;

public class SpeedSenderMain {

	private static SpeedListener.Client connection;
	/**
	 * @param args
	 * @throws TException 
	 * @throws IOException 
	 * @throws UnknownHostException 
	 */
	public static void main(String[] args) throws TException, UnknownHostException, IOException {
//		System.out.println("Starting client");
		ServiceManager.Client finder=ServiceConnector.getServiceManager();
		if (finder==null)
		{
			System.out.println("Failed to connect to Manager, quitting");
			return;
		}
		ServiceLocation there=finder.getServiceLocation("SpeedListener");
//		System.out.println("Found server at "+there.address+":"+there.port);
		TTransport transport=new TSocket(there.address,there.port);
		transport.open();
		
		connection=new SpeedListener.Client(new TBinaryProtocol(transport));
		//pingtest();
		//quicktest();
		//longtest();
		//superlongtest();
		pingNewManagerConnects();
	}
	
	private static void pingNewManagerConnects() throws TException, UnknownHostException, IOException
	{
		SpeedListener.Iface connection;
		int longrounds=200;
		int rounds=200;
//		System.out.println("Starting client");
		ServiceManager.Client finder=ServiceConnector.getServiceManager();
		if (finder==null)
		{
			System.out.println("Failed to connect to Manager, quitting");
			return;
		}
		ServiceLocation there=finder.getServiceLocation("SpeedListener");
		System.out.println("Found server at "+there.address+":"+there.port);
		
		for (int test=0; test<longrounds; test++)
		{
			long starttime=System.nanoTime();
			for (int count=0; count<rounds; count++)
			{
				connection=ServiceConnector.getSpeedListener();
				connection.ping();
			}
			long elapsed=System.nanoTime()-starttime;
			System.out.println(test+","+(elapsed*1.0/rounds/1000.0));
		}
	}
	
	private static void pingNewConnects() throws TException, UnknownHostException, IOException
	{
		SpeedListener.Iface connection;
		int longrounds=200;
		int rounds=200;
//		System.out.println("Starting client");
		ServiceManager.Client finder=ServiceConnector.getServiceManager();
		
		if (finder==null)
		{
			System.out.println("Failed to connect to Manager, quitting");
			return;
		}
		ServiceLocation there=finder.getServiceLocation("SpeedListener");
		System.out.println("Found server at "+there.address+":"+there.port);
		
		for (int test=0; test<longrounds; test++)
		{
			long starttime=System.nanoTime();
			for (int count=0; count<rounds; count++)
			{
				TProtocol protocol = ServiceConnector.getPooledConnection(there);
				connection=new SpeedListener.Client(protocol);
				connection.ping();
			}
			long elapsed=System.nanoTime()-starttime;
			System.out.println(test+","+(elapsed*1.0/rounds/1000.0));
		}
	}
	
	private static void pingtest() throws TException
	{
		System.out.println("test#,microseconds");
		int longrounds=10;
		int rounds=10;
		for (int test=0; test<longrounds; test++)
		{
			long starttime=System.nanoTime();
			for (int count=0; count<rounds; count++)
				connection.ping();
			long elapsed=System.nanoTime()-starttime;
			System.out.println(test+","+(elapsed*1.0/rounds/1000.0));
		}
	}
	
	private static void quicktest() throws TException
	{
		System.out.println("bytes,microseconds");
		int[] tests={1024, 4*1024, 64*1024, 256*1024, 1024*1024, 4*1024*1024, 8*1024*1024, 16*1024*1024, 32*1024*1024, 64*1024*1024};
		int rounds=30;
		for (int test=0; test<tests.length; test++)
		{
			byte[] testBytes=new byte[tests[test]];
			long starttime=System.nanoTime();
			for (int count=0; count<rounds; count++)
				connection.absorbBytes(testBytes.length, ByteBuffer.wrap(testBytes));
			long elapsed=System.nanoTime()-starttime;
			System.out.println(tests[test]+","+(elapsed*1.0/rounds/1000.0));
			testBytes=null;
		}
//		System.out.println("This is my local console");
	}
	
	private static void longtest() throws TException
	{
		System.out.println("bytes,microseconds");
		int start=0;
		int stop=64*1024*1024;
		
		int rounds=10;
		int reruns=5;
		for (int test=start; test<stop; test=(int)(test*1.1)+1)
		{
			byte[] testBytes=new byte[test];
			for (int run=0; run<reruns; run++)
			{
				long starttime=System.nanoTime();
				for (int count=0; count<rounds; count++)
					connection.absorbBytes(testBytes.length, ByteBuffer.wrap(testBytes));
				long elapsed=System.nanoTime()-starttime;
				System.out.println(test+","+(elapsed*1.0/rounds/1000.0));
			}
			testBytes=null;
		}
	}

	
	private static void superlongtest() throws TException
	{
		System.out.println("bytes,microseconds");
		int start=0;
		int stop=64*1024*1024+2;
		
		int rounds=5;
		int reruns=5;
		for (int test=start; test<stop; test++)
		{
			byte[] testBytes=new byte[test];
			for (int run=0; run<reruns; run++)
			{
				long starttime=System.nanoTime();
				for (int count=0; count<rounds; count++)
					connection.absorbBytes(testBytes.length, ByteBuffer.wrap(testBytes));
				long elapsed=System.nanoTime()-starttime;
				System.out.println(test+","+(elapsed*1.0/rounds/1000.0));
			}
			testBytes=null;
		}
	}
}
